//
// Created by YxMin on 2024/7/5.
//
#include <network.h>
#include <cstdio>
#include "netdata.h"
#include <procedure.h>
#include "UI.h"

#define PLAYER_REQUEST_JOIN 0
#define ROOM_FULL 0
#define PLAYER_ID_SET 1
#define PLAYER_JOIN 2
#define PLAYER_QUIT 3
#define GAME_START 4
#define ROOM_OVER 5
#define PLAYER_BACK 6
#define PLAYER_LIST 7
typedef struct {
    int packId;
    const char* data;
    int dataLength;
}RoomPack;

RoomPack parseRoomPack(const char* &recBuffer);

void ParseAndHandleRoomPackFromServer(const char* recBuffer)//recBuffer字符串的内容不可修改，
{
    do {
        RoomPack pack = parseRoomPack(recBuffer);//注意处理粘包
        if (pack.packId == -1)
            continue;
        printf("[C](RP) id:%d, dataLength:%d, data:%s\n",pack.packId,pack.dataLength,pack.data);
        switch (pack.packId) {
            case PLAYER_ID_SET:
                SetMyId(*pack.data & 0x0f);
                ShowRoomUI(IsHost, ClientPlayerList, myId);
                break;
            case PLAYER_LIST:
                UpdateClientPlayerList(pack.data);
                ShowRoomUI(IsHost, ClientPlayerList, myId);
                break;
            case PLAYER_JOIN:
                ClientPlayerList[*pack.data & 0x0f] = true;
                ShowRoomUI(IsHost, ClientPlayerList, myId);
                break;
            case PLAYER_QUIT://处理玩家退出
                ClientPlayerList[*pack.data & 0x0f] = false;
                if (!GameStarted)
                    ShowRoomUI(IsHost, ClientPlayerList, myId); //更新房间UI
                break;
            case GAME_START: //游戏开始也不用销毁房间列表吧
                PlayerStartGame(ClientPlayerList);
                ResponseGameStartPack();
                printf("游戏开始\n");
                break;
            case ROOM_OVER:
                if (IsHost) {
                    DisconnectServer(true);
                    ShowInitUI();
                    IsHost = false;
                } else {
                    backFindRoomFromRemoteRoom(nullptr);
                }
                printf("房间挂了\n");
                break;
            case ROOM_FULL:
                backFindRoomFromRemoteRoom(nullptr);
                MessageBox(0,"房间已满","服务器拒绝了你",0);
                break;
        }
    } while (*recBuffer != 0);

}

void OnDisconnectServer() {
    PlayerGameOver();
    if(!IsHost)
        backFindRoomFromRemoteRoom(nullptr);
}


extern bool IsPlayerResponsedGameStart[4];
//可能被多线程同时调用
void ParseAndHandleRoomPackFromClient(ClientMessage* msg)
{
    char buffer[128];
    do {
        RoomPack pack = parseRoomPack(msg->msg);//待处理：注意处理粘包
        if (pack.packId == -1)
            continue;
        printf("[S](RP)<-(%d) id:%d, dataLength:%d, data:%s\n",msg->id,pack.packId,pack.dataLength,pack.data);
        switch (pack.packId) {
            case PLAYER_REQUEST_JOIN:
                if (GetClientCount() <= 4) {
                    SendPlayerIdSetPack(msg->id, buffer);
                    SendPlayerListPack(msg->id,buffer);
                    SendPlayerJoinPack(msg->id, buffer);
                } else {
                    SendRoomFullPack(msg->id);
                }
                break;
            case PLAYER_BACK:
                break;
            case GAME_START:
                IsPlayerResponsedGameStart[msg->id] = true;
                break;
        }
    } while(*(msg->msg) != 0);
}

void OnPlayerQuit(int id) {
    char buffer[64];
    SendPlayerQuitPack(id,buffer);
}

//结束时recBuffer指向该包最后一个字符(>)的下一个字符
RoomPack parseRoomPack(const char* &recBuffer) { //recBuffer来自network中的线程
    RoomPack pack = {-1, nullptr,0};
    const char *start,*stop;
    start = recBuffer;
    while(*start !=0) {
        stop = start+1;
        if (*start == '<' && start[1] == '[' && start[2] != 0) {
            stop = start + 3;
            while(*stop != 0) {
                if (*stop == ']' && stop[1] =='>') {
                    pack.packId = (int)(start[2] & 0x0f);
                    start += 3; //此时start指向data第一位，而stop指向）
                    pack.data = start;
                    pack.dataLength = (int)(stop - start);
                    stop += 2;//stop指到>后一位
                    recBuffer = stop;
                    return pack;
                }
                stop++;
            }
        }
        start++;
    }
    recBuffer = stop;
    return pack;
}